package ua.yandex.shad.tempseries;

import ua.yandex.shad.tempseries.IllegalTemperatureValueException;

public class TemperatureSeriesAnalysis {

    private final double minTemperature = -273.0;
    private final double[] temperatureSeries;

    public TemperatureSeriesAnalysis(double[] temperatureSeries)
            throws IllegalTemperatureValueException {
        this.temperatureSeries = temperatureSeries;
        if (temperatureSeries != null) {
            for (int i = 0; i < temperatureSeries.length;
                    i++) {
                if (temperatureSeries[i] < minTemperature) {
                    throw new IllegalTemperatureValueException("low temperature");
                }
            }
        }
    }

    public double calcAverageTemp() {
        if (temperatureSeries == null||(temperatureSeries.length == 0)) {
            return 0;
        }
        double sum = 0;

        for (double d : temperatureSeries) {
            sum += d;
        }
        return sum / temperatureSeries.length;
    }

    public double calcTempDeviation() {
        if ((temperatureSeries == null) || (temperatureSeries.length == 0)) {
            return 0;
        }
        double deviation = 0;
        double averageTemp = calcAverageTemp();
        for (int i = 0; i < temperatureSeries.length; i++) {
            deviation += Math.pow((temperatureSeries[i] - averageTemp), 2);
        }
        deviation = Math.sqrt(deviation / temperatureSeries.length);
        return deviation;
    }

    public double findTempClosestToZero() {
        return findTempClosestToValue(0.0);
    }

    public double findTempClosestToValue(double tempValue) {
        if ((temperatureSeries == null)||(temperatureSeries.length == 0)) {
            return 0;
        } else {
            double closest = temperatureSeries[0];
            for (int i = 1; i < temperatureSeries.length; i++) {
                if ((Math.abs(temperatureSeries[i] - tempValue)
                        < Math.abs(closest - tempValue))
                        || (temperatureSeries[i] - tempValue
                        == Math.abs(closest - tempValue))) {
                    closest = temperatureSeries[i];
                }
            }
            return closest;
        }
    }

    public double[] findTempsLessThen(double tempValue) {
        if (temperatureSeries == null) {
            return null;
        }
        int count = 0;
        for (int i = 0; i < temperatureSeries.length; i++) {
            if (temperatureSeries[i] < tempValue) {
                count += 1;
            }
        }
        double[] tempsLess = new double[count];
        int j = 0;
        for (int i = 0; (i < temperatureSeries.length) && (j < count); i++) {
            if (temperatureSeries[i] < tempValue) {
                tempsLess[j] = temperatureSeries[i];
                j += 1;
            }
        }
        return tempsLess;
    }

    public double[] findTempsGreaterThen(double tempValue) {
        if (temperatureSeries == null) {
            return null;
        }
        int count = 0;
        for (int i = 0; i < temperatureSeries.length; i++) {
            if (temperatureSeries[i] > tempValue) {
                count += 1;
            }
        }
        double[] tempsGreater = new double[count];
        int j = 0;
        for (int i = 0; (i < temperatureSeries.length) && (j < count); i++) {
            if (temperatureSeries[i] > tempValue) {
                tempsGreater[j] = temperatureSeries[i];
                j += 1;
            }
        }
        return tempsGreater;
    }

    public double[] forecatsTemp(double tempValue) {
        return new double[]{};
    }
}
